package com.chuangdun.flutter.plugin.alarm

import android.app.AlarmManager
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.media.AudioAttributes
import android.os.Build
import android.util.Log
import androidx.core.app.NotificationCompat
import java.util.Calendar

class AlarmReceiver : BroadcastReceiver() {

    companion object {
        const val ALARM_ACTION = "com.chuangdun.flutter.alarm.ALARM_ACTION"

        @JvmStatic
        fun getRequestCode(tag: String, alarmId: String): Int {
            // 确保requestCode为非负数，避免潜在问题
            return "${tag}${alarmId}".hashCode() and 0x7FFFFFFF
        }

        @JvmStatic
        fun createAlarmIntent(
            context: Context,
            tag: String,
            alarmId: String,
            title: String,
            body: String,
            isRepeating: Boolean = false
        ): Intent {
            val intent = Intent(context, AlarmReceiver::class.java)
            intent.action = ALARM_ACTION
            intent.putExtra("tag", tag)
            intent.putExtra("alarmId", alarmId)
            intent.putExtra("title", title)
            intent.putExtra("body", body)
            intent.putExtra("isRepeating", isRepeating)
            return intent
        }

        @JvmStatic
        fun createBroadcastPendingIntent(
            context: Context,
            requestCode: Int,
            intent: Intent
        ): PendingIntent {
            // 使用 FLAG_MUTABLE 以允许更新 Intent 的 extras。
            // 这对于需要传递动态数据（如 alarmId, title 等）的 PendingIntent 至关重要。
            // FLAG_IMMUTABLE 会阻止对已创建 PendingIntent 的 Intent 进行修改。
            val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
            } else {
                PendingIntent.FLAG_UPDATE_CURRENT
            }
            return PendingIntent.getBroadcast(context, requestCode, intent, flags)
        }
    }

    override fun onReceive(context: Context, intent: Intent) {
        when (intent.action) {
            ALARM_ACTION -> {
                Log.d(TAG, "onReceive: 收到闹钟广播")
                fireAlarm(context, intent)
            }
        }
    }

    private fun fireAlarm(context: Context, intent: Intent) {
        val alarmId = intent.getStringExtra("alarmId") ?: return
        val tag = intent.getStringExtra("tag") ?: return
        val title = intent.getStringExtra("title") ?: "闹钟提醒"
        val body = intent.getStringExtra("body") ?: "您有一个提醒"
        val isRepeating = intent.getBooleanExtra("isRepeating", false)

        // 检查应用是否在前台运行
        if (AlarmUtils.isAppInForeground(context)) {
            // 应用在前台时，使用Activity提醒用户
            showAlarmDialog(context, tag, alarmId, title, body, isRepeating)
        } else {
            // 应用在后台时，使用Notification提醒用户
            showFullScreenNotification(context, tag, alarmId, title, body, isRepeating)
        }
        scheduleNextAlarm(context, tag, alarmId)
    }

    private fun showAlarmDialog(
        context: Context,
        tag: String,
        alarmId: String,
        title: String,
        body: String,
        isRepeating: Boolean
    ) {
        try {
            val dialogIntent = Intent(context, AlarmDialogActivity::class.java).apply {
                putExtra("tag", tag)
                putExtra("alarmId", alarmId)
                putExtra("title", title)
                putExtra("body", body)
                putExtra("isRepeating", isRepeating)

                // 必要的Activity启动标志
                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
                addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
                addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
                addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)

                // Android 10+ 绕过后台启动限制的标志
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT)
                    addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
                }
            }

            context.startActivity(dialogIntent)
            Log.d(TAG, "成功启动提醒对话框: $title")
        } catch (e: Exception) {
            Log.e(TAG, "无法启动提醒对话框: ${e.message}")
        }
    }

    /**
     * 显示通知提醒的方法
     * 点击通知将直接打开应用主页
     */
    private fun showFullScreenNotification(
        context: Context,
        tag: String,
        alarmId: String,
        title: String,
        body: String,
        isRepeating: Boolean
    ) {
        try {
            // 创建启动应用主页的Intent
            val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)
            val contentIntent = if (launchIntent != null) {
                // 添加标志确保应用正确启动
                launchIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP)
                PendingIntent.getActivity(
                    context,
                    getRequestCode(tag, alarmId), // 使用相同的requestCode
                    launchIntent,
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
                    } else {
                        PendingIntent.FLAG_UPDATE_CURRENT
                    }
                )
            } else {
                null
            }

            // 创建通知渠道（Android 8.0及以上版本需要）
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val channelId = "alarm_channel"
                val channelName = "闹钟提醒"
                val channel = NotificationChannel(
                    channelId,
                    channelName,
                    NotificationManager.IMPORTANCE_HIGH
                )
                // 设置通知声音为自定义铃声或系统默认闹钟铃声
                val alarmSoundUri = AlarmUtils.getAlarmSoundUri(context)
                channel.setSound(
                    alarmSoundUri, AudioAttributes.Builder()
                        .setUsage(AudioAttributes.USAGE_ALARM) // 使用闹钟用途，音量更大
                        .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                        .build()
                )
                // 设置震动模式：持续10秒，震动1秒、暂停1秒循环
                channel.vibrationPattern =
                    longArrayOf(0, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000)
                channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
                channel.enableLights(true) // 启用LED灯
                channel.lightColor = 0xFF0000FF.toInt() // 设置LED灯颜色为蓝色
                val notificationManager =
                    context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                notificationManager.createNotificationChannel(channel)
            }

            // 创建通知
            val notificationBuilder = NotificationCompat.Builder(context, "alarm_channel")
                .setContentTitle(title)
                .setContentText(body)
                .setSmallIcon(android.R.drawable.ic_lock_idle_alarm) // 使用系统默认图标
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setCategory(NotificationCompat.CATEGORY_ALARM)
                .setAutoCancel(true)
                .setSound(AlarmUtils.getAlarmSoundUri(context)) // 设置通知声音为自定义铃声或系统默认闹钟铃声
                .setVibrate(
                    longArrayOf(
                        0,
                        1000,
                        1000,
                        1000,
                        1000,
                        1000,
                        1000,
                        1000,
                        1000,
                        1000,
                        1000
                    )
                ) // 设置震动模式：持续10秒，震动1秒、暂停1秒循环
                .setLights(0xFF0000FF.toInt(), 1000, 1000) // 设置LED灯闪烁（蓝色，亮1秒，暗1秒）
                .setFullScreenIntent(contentIntent, true) // 全屏显示通知，确保在锁屏上也能显示
                .setStyle(NotificationCompat.BigTextStyle().bigText(body)) // 使用BigTextStyle以支持更长的通知文本

            // 设置通知点击意图
            if (contentIntent != null) {
                notificationBuilder.setContentIntent(contentIntent)
            }

            val notification = notificationBuilder.build()
            // 显示通知
            val notificationManager =
                context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.notify(getRequestCode(tag, alarmId), notification)
            Log.d(TAG, "成功显示通知提醒: $title")
        } catch (e: Exception) {
            Log.e(TAG, "无法显示通知提醒: ${e.message}")
        }
    }

    /**
     * 为重复闹钟安排下一次触发。
     * 为了增强健壮性，此方法会从数据库中获取最新的闹钟信息，
     * 并计算出距离当前时间最近的未来触发时间点。
     */
    private fun scheduleNextAlarm(context: Context, tag: String, alarmId: String) {
        try {
            val databaseHelper = AlarmDatabaseHelper(context)
            val alarmModel = databaseHelper.getAlarmByAlarmId(alarmId, tag) ?: return

            if (!alarmModel.repeating) {
                Log.w(TAG, "尝试为非重复闹钟 $alarmId 安排下次触发。")
                return
            }

            val now = System.currentTimeMillis()
            val calendar = Calendar.getInstance()
            // 设置为今天指定的时间
            calendar.set(Calendar.HOUR_OF_DAY, alarmModel.hour)
            calendar.set(Calendar.MINUTE, alarmModel.minute)
            calendar.set(Calendar.SECOND, 0)
            calendar.set(Calendar.MILLISECOND, 0)

            // 如果今天的时间已过，则移动到明天
            while (calendar.timeInMillis <= now) {
                calendar.add(Calendar.DAY_OF_MONTH, 1)
            }

            // 设置下一次闹钟，使用AlarmManager.setAlarmClock以提供更好的用户体验
            val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
            val alarmIntent =
                createAlarmIntent(context, tag, alarmId, alarmModel.title, alarmModel.body, true)
            val requestCode = getRequestCode(tag, alarmId)
            val pendingIntent = createBroadcastPendingIntent(
                context,
                requestCode,
                alarmIntent
            )

            // 创建显示在时钟应用中的信息
            val alarmInfo = AlarmManager.AlarmClockInfo(calendar.timeInMillis, pendingIntent)

            // 使用setAlarmClock设置闹钟
            alarmManager.setAlarmClock(alarmInfo, pendingIntent)
            Log.d(TAG, "已为重复闹钟 $alarmId 安排下次触发时间: ${calendar.time}")
        } catch (e: Exception) {
            Log.e(TAG, "无法设置下一次闹钟 for $alarmId: ${e.message}", e)
        }
    }
}